/* Copyright (C) 2005-2013, Unigine Corp. All rights reserved.
 *
 * File:    fragment_base_light.h
 * Desc:    Mesh base light shader
 * Version: 1.30
 * Author:  Alexander Zapryagaev <frustum@unigine.com>
 *
 * This file is part of the Unigine engine (http://unigine.com/).
 *
 * Your use and or redistribution of this software in source and / or
 * binary form, with or without modification, is subject to: (i) your
 * ongoing acceptance of and compliance with the terms and conditions of
 * the Unigine License Agreement; and (ii) your inclusion of this notice
 * in any version of this software that you use or redistribute.
 * A copy of the Unigine License Agreement is available by contacting
 * Unigine Corp. at http://unigine.com/
 */

/******************************************************************************\
*
* OpenGL
*
\******************************************************************************/

#ifdef OPENGL
	
	#ifndef FRAGMENT_BASE_LIGHT
		#define FRAGMENT_BASE_LIGHT
		
		uniform sampler2D s_texture_0;
		uniform sampler2D s_texture_1;
		uniform sampler2D s_texture_2;
		uniform sampler2D s_texture_3;
		uniform sampler2D s_texture_4;
		uniform sampler2D s_texture_5;
		
		uniform half4 detail_transform;
		uniform half4 diffuse_color;
		uniform half4 specular_color;
		
	#else
		
		#include <core/shaders/default/mesh/fragment_base_sample.h>
		
		#ifdef USE_TESSELLATION && TESSELLATION
			
			half3 vertex_normal = normalize(s_texcoord_1.xyz);
			half3 vertex_tangent = normalize(s_texcoord_2.xyz);
			half3 vertex_binormal = normalize(cross(vertex_normal,vertex_tangent) * half(s_texcoord_2.w));
			
			half3 camera_direction = half3(-s_texcoord_3.xyz);
			
			#ifdef PHONG_RIM || !QUALITY_MEDIUM
				
				half3 screen_normal = normalize(vertex_tangent * normal.x + vertex_binormal * normal.y + vertex_normal * (normal.z * s_polygon_front));
				
				#ifdef OMNI
					half4 light_direction = half4(getOmniRadius(s_light_position - s_texcoord_3.xyz) * s_light_iradius.w,s_light_iradius.w * s_light_iradius.w);
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#endif
				#elif PROJ
					half4 light_direction = half4((s_light_position - s_texcoord_3.xyz) * (s_light_iradius.x * s_light_iradius.w),s_light_iradius.w * s_light_iradius.w);
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#endif
				#elif WORLD
					half3 light_direction = s_light_direction;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,screen_normal,light_direction);
					#else
						half3 color = getDiffuse(s_material_shading,diffuse.xyz,screen_normal,light_direction);
					#endif
					color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,screen_normal,light_direction,camera_direction);
				#endif
				
			#elif ANISOTROPY
				
				camera_direction = half3(dot(camera_direction,vertex_tangent),dot(camera_direction,vertex_binormal),dot(camera_direction,vertex_normal));
				camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
				
				#ifdef OMNI
					half4 light_direction = half4(getOmniRadius(s_light_position - s_texcoord_3.xyz) * s_light_iradius.w,s_light_iradius.w * s_light_iradius.w);
					half attenuation = getAttenuate(light_direction);
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#elif PROJ
					half4 light_direction = half4((s_light_position - s_texcoord_3.xyz) * (s_light_iradius.x * s_light_iradius.w),s_light_iradius.w * s_light_iradius.w);
					half attenuation = getAttenuate(light_direction);
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#elif WORLD
					half3 light_direction = s_light_direction;
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#endif
				
			#endif
			
		#else
			
			#ifdef PHONG_RIM || !QUALITY_MEDIUM
				
				half3 camera_direction = s_texcoord_2.xyz;
				
				#ifdef WORLD
					half3 light_direction = s_texcoord_1.xyz;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,normal,light_direction);
					#else
						half3 color = getDiffuse(s_material_shading,diffuse.xyz,normal,light_direction);
					#endif
					color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,normal,light_direction,camera_direction);
				#else
					half4 light_direction = s_texcoord_1;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
					#endif
				#endif
				
			#elif ANISOTROPY
				
				half3 camera_direction = s_texcoord_2.xyz;
				camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
				
				#ifdef WORLD
					half3 light_direction = s_texcoord_1.xyz;
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#else
					half4 light_direction = s_texcoord_1;
					half attenuation = getAttenuate(light_direction);
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#endif
				
			#endif
			
		#endif
		
	#endif
	
/******************************************************************************\
*
* Direct3D11
*
\******************************************************************************/

#elif DIRECT3D11
	
	#ifndef FRAGMENT_BASE_LIGHT
		#define FRAGMENT_BASE_LIGHT
		
		Texture2D s_texture_0 : register(t0);
		Texture2D s_texture_1 : register(t1);
		Texture2D s_texture_2 : register(t2);
		Texture2D s_texture_3 : register(t3);
		Texture2D s_texture_4 : register(t4);
		Texture2D s_texture_5 : register(t5);
		
		cbuffer shader_parameters {
			#ifdef OVERLAY_0 || OVERLAY_1 || MULTIPLY_0 || MULTIPLY_1
				float4 detail_transform;
			#endif
			float4 diffuse_color;
			float4 specular_color;
		};
		
	#else
		
		#include <core/shaders/default/mesh/fragment_base_sample.h>
		
		#ifdef USE_TESSELLATION && TESSELLATION
			
			half3 vertex_normal = normalize(IN.texcoord_1);
			half3 vertex_tangent = normalize(IN.texcoord_2.xyz);
			half3 vertex_binormal = normalize(cross(vertex_normal,vertex_tangent) * IN.texcoord_2.w);
			
			half3 camera_direction = -IN.texcoord_3;
			
			#ifdef PHONG_RIM || !QUALITY_MEDIUM
				
				half3 screen_normal = normalize(vertex_tangent * normal.x + vertex_binormal * normal.y + vertex_normal * (normal.z * s_polygon_front));
				
				#ifdef OMNI
					half4 light_direction = half4(getOmniRadius(s_light_position - IN.texcoord_3) * s_light_iradius.w,s_light_iradius.w * s_light_iradius.w);
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#endif
				#elif PROJ
					half4 light_direction = half4((s_light_position - IN.texcoord_3) * (s_light_iradius.x * s_light_iradius.w),s_light_iradius.w * s_light_iradius.w);
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,screen_normal,light_direction,camera_direction);
					#endif
				#elif WORLD
					half3 light_direction = s_light_direction;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,screen_normal,light_direction);
					#else
						half3 color = getDiffuse(s_material_shading,diffuse.xyz,screen_normal,light_direction);
					#endif
					color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,screen_normal,light_direction,camera_direction);
				#endif
				
			#elif ANISOTROPY
				
				camera_direction = half3(dot(camera_direction,vertex_tangent),dot(camera_direction,vertex_binormal),dot(camera_direction,vertex_normal));
				camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
				
				#ifdef OMNI
					half4 light_direction = half4(getOmniRadius(s_light_position - IN.texcoord_3) * s_light_iradius.w,s_light_iradius.w * s_light_iradius.w);
					half attenuation = getAttenuate(light_direction);
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#elif PROJ
					half4 light_direction = half4((s_light_position - IN.texcoord_3) * (s_light_iradius.x * s_light_iradius.w),s_light_iradius.w * s_light_iradius.w);
					half attenuation = getAttenuate(light_direction);
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#elif WORLD
					half3 light_direction = s_light_direction;
					light_direction.xyz = half3(dot(light_direction.xyz,vertex_tangent),dot(light_direction.xyz,vertex_binormal),dot(light_direction.xyz,vertex_normal));
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#endif
				
			#endif
			
		#else
			
			#ifdef PHONG_RIM || !QUALITY_MEDIUM
				
				half3 camera_direction = IN.texcoord_2.xyz;
				
				#ifdef WORLD
					half3 light_direction = IN.texcoord_1.xyz;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,normal,light_direction);
					#else
						half3 color = getDiffuse(s_material_shading,diffuse.xyz,normal,light_direction);
					#endif
					color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,normal,light_direction,camera_direction);
				#else
					half4 light_direction = IN.texcoord_1;
					#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
						half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
					#else
						half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
					#endif
				#endif
				
			#elif ANISOTROPY
				
				half3 camera_direction = IN.texcoord_2.xyz;
				camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
				
				#ifdef WORLD
					half3 light_direction = IN.texcoord_1.xyz;
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#else
					half4 light_direction = IN.texcoord_1;
					half attenuation = getAttenuate(light_direction);
					light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
					half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
				#endif
				
			#endif
			
		#endif
		
	#endif
	
/******************************************************************************\
*
* Direct3D9
*
\******************************************************************************/

#elif DIRECT3D9
	
	#ifndef FRAGMENT_BASE_LIGHT
		#define FRAGMENT_BASE_LIGHT
		
		half4 detail_transform;
		half4 diffuse_color;
		half4 specular_color;
		
	#else
		
		#include <core/shaders/default/mesh/fragment_base_sample.h>
		
		#ifdef PHONG_RIM || !QUALITY_MEDIUM
			
			half3 camera_direction = IN.texcoord_2.xyz;
			
			#ifdef WORLD
				half3 light_direction = IN.texcoord_1.xyz;
				#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
					half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,normal,light_direction);
				#else
					half3 color = getDiffuse(s_material_shading,diffuse.xyz,normal,light_direction);
				#endif
				color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,normal,light_direction,camera_direction);
			#else
				half4 light_direction = IN.texcoord_1;
				#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
					half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#else
					half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#endif
			#endif
			
		#elif ANISOTROPY
			
			half3 camera_direction = IN.texcoord_2.xyz;
			camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
			
			#ifdef WORLD
				half3 light_direction = IN.texcoord_1.xyz;
				light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
				half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
			#else
				half4 light_direction = IN.texcoord_1;
				half attenuation = getAttenuate(light_direction);
				light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
				half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
			#endif
			
		#endif
		
	#endif
	
/******************************************************************************\
*
* PlayStation3
*
\******************************************************************************/

#elif PLAYSTATION3
	
	#ifndef FRAGMENT_BASE_LIGHT
		#define FRAGMENT_BASE_LIGHT
		
		uniform sampler2D s_texture_0 : TEXUNIT0;
		uniform sampler2D s_texture_1 : TEXUNIT1;
		uniform sampler2D s_texture_2 : TEXUNIT2;
		uniform sampler2D s_texture_3 : TEXUNIT3;
		uniform sampler2D s_texture_4 : TEXUNIT4;
		uniform sampler2D s_texture_5 : TEXUNIT5;
		
		uniform half4 detail_transform;
		uniform half4 diffuse_color;
		uniform half4 specular_color;
		
	#else
		
		#include <core/shaders/default/mesh/fragment_base_sample.h>
		
		#ifdef PHONG_RIM || !QUALITY_MEDIUM
			
			half3 camera_direction = IN.texcoord_2.xyz;
			
			#ifdef WORLD
				half3 light_direction = IN.texcoord_1.xyz;
				#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
					half3 color = getDiffuseRim(s_material_shading,s_material_phong_rim,diffuse.xyz,normal,light_direction);
				#else
					half3 color = getDiffuse(s_material_shading,diffuse.xyz,normal,light_direction);
				#endif
				color += getSpecularFresnelNormalize(s_material_shading,s_material_fresnel,specular,normal,light_direction,camera_direction);
			#else
				half4 light_direction = IN.texcoord_1;
				#ifdef USE_PHONG_RIM && QUALITY_MEDIUM
					half3 color = getDiffuseRimSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_phong_rim,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#else
					half3 color = getDiffuseSpecularFresnelNormalizeAttenuate(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
				#endif
			#endif
			
		#elif ANISOTROPY
			
			half3 camera_direction = IN.texcoord_2.xyz;
			camera_direction.xy = half2(dot(camera_direction.xy,s_material_anisotropy.xy),dot(camera_direction.xy,s_material_anisotropy.zw));
			
			#ifdef WORLD
				half3 light_direction = IN.texcoord_1.xyz;
				light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
				half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction,camera_direction);
			#else
				half4 light_direction = IN.texcoord_1;
				half attenuation = getAttenuate(light_direction);
				light_direction.xy = half2(dot(light_direction.xy,s_material_anisotropy.xy),dot(light_direction.xy,s_material_anisotropy.zw));
				half3 color = getDiffuseSpecularFresnelNormalize(s_material_shading,s_material_fresnel,diffuse.xyz,specular,normal,light_direction.xyz,camera_direction) * attenuation;
			#endif
			
		#endif
		
	#endif
	
#endif
